/** @file sqlite_dataset.cc
 *
 *  @author Dongryeol Lee (drselee@gmail.com)
 */

#include <fstream>
#include <functional>
#include <ios>

#include "core/data/csv_parser.h"
#include "core/data/sqlite_dataset.h"

namespace core {
namespace data {

SqliteDataset::SqliteDataset() {
  average_num_points_ = 0.0;
  db_connection_ = NULL;
  num_points_ = 0;
}

SqliteDataset::~SqliteDataset() {
  sqlite3_close(db_connection_);
}

double SqliteDataset::average_num_points() const {
  return average_num_points_;
}

arma::vec &SqliteDataset::get_instance(int point_id) {

}

const arma::vec &SqliteDataset::get_instance(int point_id) const {

}

core::data::alias_vec &SqliteDataset::get_instance(
  int point_id, core::data::alias_vec **targets_out) {

}

const core::data::alias_vec &SqliteDataset::get_instance(
  int point_id,
  const core::data::alias_vec **targets_out) const {

}

void SqliteDataset::Init(int num_attributes_in, int num_points_in) {

}

void SqliteDataset::Init(
  boost::mpi::communicator &world,
  const std::string &file_name_in, bool from_single_file)  {

}

bool SqliteDataset::Init(const std::string &file_name_in) {

  // Open a DB connection.
  std::string file_name_part =
    file_name_in.substr(0, file_name_in.find(":"));
  std::string table_name_part =
    file_name_in.substr(file_name_in.find(":") + 1);
  std::cerr
      << "SqliteDataset::Init: Reading from the DB " <<
      file_name_part << " for the table name " << table_name_part << "...\n";
  sqlite3_open(file_name_part.c_str(), &db_connection_);

  // SELECT COUNT(*) FROM <table name> to count the number of points.
  std::string count_sql_statement("SELECT COUNT(*) FROM ");
  count_sql_statement.append(table_name_part);
  char *error_message = NULL;
  sqlite3_stmt *count_statement = NULL;
  sqlite3_prepare(
    db_connection_, count_sql_statement.c_str(), -1, &count_statement, NULL);
  while(sqlite3_step(count_statement) == SQLITE_ROW) {
    num_points_ = sqlite3_column_int(count_statement, 0);
    std::cerr << "   found " << num_points_ << " points...\n";
  }
  sqlite3_finalize(count_statement);
  average_num_points_ = num_points_;
  return true;
}

void SqliteDataset::Init(
  boost::mpi::communicator &world, int num_attributes, int num_points) {
  this->core::data::Dataset::Init(world, num_attributes, num_points);
}

int SqliteDataset::num_points() const {
  return num_points_;
}

void SqliteDataset::RandomGenerate(
  boost::mpi::communicator &world, int num_dimensions, int num_points) {
}
}
}
